using System;
using IStrong.EC.Abstractions.Extensions;
using IStrong.EC.DAO;
using IStrong.EC.DAO.Abstractions;
using IStrong.EC.DAO.Abstractions.Interfaces;
using IStrong.EC.DAO.Mapping.Xml;
using IStrong.EC.Web.Extensions;
using IStrong.EC.Web.Filters;
using IStrong.EC.Web.ModelBinding;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using NSwag.AspNetCore;
using System.IO;
using System.Net;
using System.Net.Http;
using AutoMapper;
using Microsoft.Extensions.Options;
using Polly;
using Senparc.CO2NET;
using Senparc.CO2NET.RegisterServices;
using Senparc.Weixin;
using Senparc.Weixin.Entities;
using Senparc.Weixin.RegisterServices;

namespace IStrong.EC.WebApi.Results
{
    /// <summary>
    /// 启动类
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="configuration">依赖注入配置</param>
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            //读取数据库连接串
            //DbProviderManager.LoadConfiguration(configuration);

        }

        /// <summary>
        /// 配置信息
        /// </summary>
        public IConfiguration Configuration { get; }


        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">服务容器</param>
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => false; // 这里设置true session将失效
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            //注册本地服务，类库名称以IStrong开头，继承IService接口的类会自动注册到服务里
            services.AddLocalService();
            //添加Session支持
            services.AddSession();
            //启用内存缓存
            services.AddMemoryCache();
            // 
            services.AddDatabaseFeature();
            //注册数据访问类
            services.AddSingleton<IDbContext, DbContext>();
            //注册mapping
            services.AddSingleton<IMappingProvider, XmlMappingProvider>();
            //启用HttpClient 
            services.AddHttpClient();
            services.AddHttpClient("rtxUser", client =>
                {
                    client.BaseAddress = new Uri(Configuration["userLoginUrl"]);
                    //client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
                }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
                {
                    UseProxy = false
                    //,
                    //AllowAutoRedirect = false,
                    //AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
                }); ;
            //.AddTransientHttpErrorPolicy(builder => builder.CircuitBreakerAsync(
            //    handledEventsAllowedBeforeBreaking: 3,
            //    durationOfBreak: TimeSpan.FromSeconds(5)
            //));
            //.AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(new[]
            //{
            //    TimeSpan.FromSeconds(1),
            //    TimeSpan.FromSeconds(5),
            //    TimeSpan.FromSeconds(10)
            //}));

            //启用跨域
            services.AddCors();
            services.AddMvc(options =>
            {
                //添加参数绑定
                options.ModelBinderProviders.Insert(0, new StringToListBinderProvider());
                //添加全局异常处理过滤器
                options.Filters.Add<GlobalExceptionFilter>();
            })
            .AddJsonOptions(options =>
            {
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
            })
            .AddAssemblies()//动态加载控制器dll
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            //添加对AutoMapper的支持
            services.AddAutoMapper();

            services.AddSenparcGlobalServices(Configuration)//Senparc.CO2NET 全局注册
                .AddSenparcWeixinServices(Configuration);//Senparc.Weixin 注册

            #region 本地化和全球化（如果需要请取消注释）

            //services.AddPortableObjectLocalization(opts => opts.ResourcesPath = "Resources");
            //services.AddMvc().AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix);
            //services.Configure<RequestLocalizationOptions>(options =>
            //{
            //    var supportedCultures = new List<CultureInfo>
            //{
            //    new CultureInfo("en-US"),
            //    new CultureInfo("en"),
            //    new CultureInfo("fr-FR"),
            //    new CultureInfo("fr"),
            //    new CultureInfo("zh-cn")
            //};

            //    options.DefaultRequestCulture = new RequestCulture("zh-cn");
            //    options.SupportedCultures = supportedCultures;
            //    options.SupportedUICultures = supportedCultures;
            //});

            #endregion 本地化和全球化（如果需要请取消注释）


        }

        /// <summary>
        /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        /// </summary>
        /// <param name="app"></param>
        /// <param name="env"></param>
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
        {
            app.UseDefaultFiles();
            //启用静态文件
            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(
                Directory.GetCurrentDirectory()),
                RequestPath = ""
            });
            //启用session
            app.UseSession();
            //参数验证
            app.UseParameterVerify();
            //通过请求支持本地化
            app.UseRequestLocalization();
            app.UseCookiePolicy();
            //集成swagger
            app.UseSwagger();
            //允许跨域
            app.UseCors(policy =>
            {
                policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
            });
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "Maintenance",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

            // 启动 CO2NET 全局注册，必须！
            IRegisterService register = RegisterService.Start(env, senparcSetting.Value)
                .UseSenparcGlobal(false, null);

            //开始注册微信信息，必须！
            register.UseSenparcWeixin(senparcWeixinSetting.Value, senparcSetting.Value);

        }
    }
}
